#pragma once

#include "PhysicsActor.hpp"




class TPhysicsActor : public PhysicsActor
{
public:

	typedef std::pair<vector3,vector3>   Force;
	typedef std::vector<Force>           Forces;

private:

	notify_t              m_destroyed;

	//
	// Geometric properties
	//

	sphere                m_boundingSphere; //< The bounding sphere defines a close volume for the actor
	std::vector<sphere>   m_spheres;
	std::vector<obb>      m_boxes;


	//
	// Kinematic quantities
	// They describe the current state of our body
	//

	ActorKinematics   m_state;


	//
	// Dynamic quantities
	// They are the quantities, responsible for changing the kinematic
	// quantities over time.
	//

	// Linear & Angular
	Forces            m_forces; //< A list of all forces, that are applied to this body during this simulation step


	//
	// User values
	//

	/// Used to link an actor with something on the game
	void*             m_userData;

public:

	TPhysicsActor(const ActorDesc& desc, const notify_t& fn);
	~TPhysicsActor();

	void update(float_t dt);


	const ActorKinematics& state() const;

	float_t mass() const;

	vector3 position() const;
	void setPosition(const vector3& p);

	matrix3x3 rotation() const;
	void setRotation(const matrix3x3&);

	matrix4x4 transform() const;
	void setTransform(const matrix4x4&);

	vector3 velocity() const;
	void setVelocity(const vector3& v);
	void addVelocity(const vector3& v);

	vector3 impulse() const;
	void setImpulse(const vector3& p);
	void addImpulse(const vector3& p);

	void addForce(const vector3& f);
	void addForce(const vector3& p, const vector3& f);

	RayCastResult rayCast(const ray& ray_) const;

	void debugRender(MeshVertices& vertices, Indices32 &indices, MeshVertices& tmpVertices, Indices32& tmpIndices) const;
};
///////////////////////////////////////////////////////////////////////////////////////////////////

DEFINE_LOOSE_PTR(TPhysicsActor);
